#include "epoller.h"

Epoller::Epoller(int maxEvent)
    : epollFd_(epoll_create(512))
    , events_(maxEvent)
{
    assert(epollFd_ >= 0 && events_.size() > 0);
}

Epoller::~Epoller()
{
    close(epollFd_);
}

// 将指定的文件描述符 fd 添加到 epoll 实例中进行监听，并指定要监听的事件类型 events
bool Epoller::addFd(int fd, uint32_t events)
{
    if(fd < 0)
        return false;
    // 初始化监听的文件描述符及其相关事件
    epoll_event ev = {0};
    ev.data.fd = fd;
    ev.events = events;
    return epoll_ctl(epollFd_, EPOLL_CTL_ADD, fd, &ev) == 0;
}

// 修改指定文件描述符 fd 的监听事件类型为 events
bool Epoller::modFd(int fd, uint32_t events)
{
    if(fd < 0)
        return false;
    epoll_event ev = {0};
    ev.data.fd = fd;
    ev.events = events;
    return epoll_ctl(epollFd_, EPOLL_CTL_MOD, fd, &ev) == 0;
}

// 从 epoll 实例中删除指定的文件描述符 fd
bool Epoller::delFd(int fd)
{
    if(fd < 0)
        return false;
    epoll_event ev = {0};
    return epoll_ctl(epollFd_, EPOLL_CTL_DEL, fd, &ev);
}

// 等待 epoll 实例中监听的文件描述符上的事件发生
int Epoller::wait(int timeOutMs)
{
    return epoll_wait(epollFd_, &events_[0], 
                static_cast<int>(events_.size()), timeOutMs);
}

// 获取 events_ 向量中第 i 个就绪事件对应的文件描述符
int Epoller::getEventFd(size_t i) const
{
    assert(i < events_.size() && i >= 0);
    return events_[i].data.fd;
}

// 获取 events_ 向量中第 i 个就绪事件的具体事件类型
uint32_t Epoller::getEvents(size_t i) const
{
    assert(i < events_.size() && i >= 0);
    return events_[i].events; 
}